#include "Camera.hpp"

Camera::Camera() {
	cameraObject.set(CV_CAP_PROP_FRAME_WIDTH, 640);
	cameraObject.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
	cameraObject.set(CV_CAP_PROP_FORMAT, CV_8UC1);

	if (!cameraObject.open()) {
		throw CameraInitException();
	}

	//this delay is necessary to avoid hardware errors.
	delay(2000);
}

Camera &Camera::getInstance() {
	static Camera *instance;

	if (!instance) {
		instance = new Camera();
	}

	return *instance;
}

cv::Mat Camera::takeImage() {
	cv::Mat image;
	if (!cameraObject.grab()) {
		throw CameraPictureError();
	}

	cameraObject.retrieve(image);

	return image;
}

cv::Mat Camera::takeFormattedImage() {
	cv::Mat picture;

	try {
		picture = takeImage();
	} catch (CameraPictureError &e) {
		throw e;
	}

	cv::Mat pictureCenter(picture.rows, picture.rows, picture.type());
	const int colOffset = (picture.cols - picture.rows) / 2;

	picture(cv::Rect(colOffset, 0, picture.rows, picture.rows)).copyTo(
			pictureCenter);

	cv::resize(pictureCenter, pictureCenter, cv::Size(100, 100));
	pictureCenter.convertTo(pictureCenter, CV_64F);

	return pictureCenter;
}

bool Camera::setProperty(int propId, double value) {
	return cameraObject.set(propId, value);
}
